/*
 * CreepBaseDirectional.java
 *
 * Created on January 4, 2008, 1:21 PM
 *
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package hextd.creep;

import hextd.util.Cache;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Point2D.Double;
import com.usoog.tdcore.gamegrid.ScaledCanvas;
import com.usoog.tdcore.gamestate.GameState;

/**
 *
 * @author hylke
 */
public abstract class CreepBaseDirectional extends CreepBase {

	private int prevPaintTime;
	private Color bodyColor;
	private Stroke bodyStroke;
	private Shape[] bodyShapes;
	private String bodySVGName;
	private boolean bodyUsesSVG;
	private double bodyScale;
	private int bodyStep = 0;
	private AffineTransform atRotate, atCorrect;
	private Point2D.Double oldLoc = new Point2D.Double();
	private Point2D.Double newLoc = new Point2D.Double();

	/** Creates a new instance of CreepBaseDirectional */
	public CreepBaseDirectional(String name) {
		super(name);
		this.bodyUsesSVG = false;
	}

	public CreepBaseDirectional(String name, boolean withImage) {
		super(name);
		this.bodyUsesSVG = withImage;
	}

	@Override
	public void init(GameState gs, HexTDCreepData data) {
		this.atRotate = new AffineTransform();
		this.atCorrect = new AffineTransform();
		super.init(gs, data);
	}

	@Override
	public void doTick(int gameTime) {
		// Do some reference shuffling to avoid having to instantiate a Point2D
		Double tempLoc = oldLoc;
		oldLoc = newLoc;
		newLoc = tempLoc;
		super.doTick(gameTime);
		getGameLocation(newLoc);
		double a = Math.atan2(newLoc.y - oldLoc.y, newLoc.x - oldLoc.x);
		this.atRotate.setToIdentity();
		this.atRotate.rotate(a);
	}

	abstract Shape[] generateShapes();

	abstract Color generateColor();

	abstract Stroke generateStroke();

	abstract String getSvgName();

	@Override
	public void resetScale(ScaledCanvas sc) {
		super.resetScale(sc);
		if (this.bodyUsesSVG) {
			this.bodySVGName = this.getSvgName();
			this.bodyScale = this.size.scaleMod * paintScale / 2;
			atCorrect.setToIdentity();
			atCorrect.setToTranslation(-this.bodyScale / 2, -this.bodyScale / 2);
		} else {
			this.bodyColor = this.generateColor();
			this.bodyShapes = this.generateShapes();
			this.bodyStroke = this.generateStroke();
		}
	}

	@Override
	public void paint(Graphics2D g2, int gameTime) {
		if (this.inactive || this.dead) {
		} else {
			Stroke defaultStroke = g2.getStroke();

			AffineTransform saveXform = g2.getTransform();
			g2.transform(atTranslate);

			if (this.shielded) {
				this.paintShield_bottom(g2);
			}

			this.paintHealthLine(g2);

			g2.transform(atRotate);
			if (this.bodyUsesSVG) {
				g2.transform(this.atCorrect);
				Cache.getInstance().renderSvgImage(this.bodySVGName, g2, (int) this.bodyScale, (int) this.bodyScale);
			} else {
				this.bodyStep += gameTime - this.prevPaintTime;
				if (this.bodyStep >= this.bodyShapes.length) {
					this.bodyStep = 0;
				}
				this.prevPaintTime = gameTime;

				g2.setColor(this.bodyColor);
				g2.setStroke(this.bodyStroke);
				g2.draw(this.bodyShapes[this.bodyStep]);
			}
			g2.setTransform(saveXform);

			if (this.shielded) {
				g2.transform(atTranslate);
				this.paintShield_top(g2);
				g2.setTransform(saveXform);
			}

			super.paintSelected(g2);

			g2.setStroke(defaultStroke);
		}
	}
}
